/*
 * Copyright (c) 2018, apexes.net. All rights reserved.
 *
 *         http://www.apexes.net
 *
 */
package net.apexes.commons.eventbus;

import java.lang.reflect.Method;
import java.util.LinkedHashSet;
import java.util.Set;

/**
 * 
 * @author <a href="mailto:hedyn@foxmail.com">HeDYn</a>
 *
 */
public class EventBus extends PriorityHub {
    
    public EventBus() {
        super(IEventHandler.class);
    }
    
    /**
     * 
     * @param address
     * @param handler
     */
    public <T> void register(final String address, final IEventHandler<T> handler) {
        verifyNotNull(address, "address");
        verifyNotNull(handler, "handler");
        super.register(address, handler);
    }
    
    /**
     * 
     * @param address
     * @param handler
     */
    public <T> void unregister(final String address, final IEventHandler<T> handler) {
        verifyNotNull(address, "address");
        verifyNotNull(handler, "handler");
        super.unregister(address, handler);
    }
    
    @Override
    protected Set<AnnotationPriority> getAnnotationPrioritys(Object object) {
        Set<AnnotationPriority> handlers = new LinkedHashSet<>();
        Class<?> clazz = object.getClass();
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            if (method.isAnnotationPresent(Subscribe.class)) {
                Class<?>[] parameterTypes = method.getParameterTypes();
                if (parameterTypes.length != 1) {
                    throw new IllegalArgumentException("The method is invalid. method=" + method);
                }
                AnnotationEventHandler handler = new AnnotationEventHandler(object, method);
                handlers.add(handler);
            }
        }
        return handlers;
    }

    @Override
    protected <E> void doPost(String address, E event, PriorityList<E> prioritys) {
        for (IPriority<E> priority : prioritys) {
            IEventHandler<E> handler = (IEventHandler<E>) priority;
            handler.handle(event);
        }
    }
    
}
